/*
 * Created on Oct 5, 2005
 *
 */
package org.mushroomdb.engine.optimizer;

import java.lang.reflect.InvocationTargetException;

import org.apache.log4j.Logger;
import org.mushroomdb.service.Service;
import org.mushroomdb.util.Properties;
import org.mushroomdb.util.PropertiesHelper;

/**
 * Creates and initializes the system's query optimizer.
 * 
 * @author mchiodi
 *
 */
public class OptimizerService implements Service {
	private Optimizer optimizer;
	private Logger logger;

	/**
	 * Default constructor.
	 */
	public OptimizerService() {
		this.logger = Logger.getLogger(this.getClass());
	}
	
	/**
	 * Returns the system's query optimizer.
	 * @return
	 */
	public Optimizer getOptimizer() {
		return this.optimizer;
	}
	
	/**
	 * @see org.mushroomdb.service.Service#initialize()
	 */
	public void initialize() {
		this.loadOptimizer();
	}

	/**
	 * Construye el interceptor.
	 */
	private void loadOptimizer() {
		CompositeOptimizer compositeOptimizer = new CompositeOptimizer();
		
		int index = 1;
		String optimizerClass = null;
		do {
			optimizerClass = Properties.getProperty(PropertiesHelper.OPTIMIZER + "." + index); //$NON-NLS-1$
			if (optimizerClass != null) {
				Optimizer optimizer = this.getOptimizerInstance(optimizerClass);
				if (optimizer != null) {
					compositeOptimizer.addOptimizer(optimizer);
					logger.info("Optimizer " + optimizerClass + " registered."); //$NON-NLS-1$ //$NON-NLS-2$
				} else {
					logger.warn("Optimizer " + optimizerClass + " was not registered."); //$NON-NLS-1$ //$NON-NLS-2$
				}
			}
			index++;
		} while (optimizerClass != null);
		
		this.optimizer = compositeOptimizer;
		
	}
	
	/**
	 * Creates the optimizer instance based on it's class name.
	 * @param className
	 * @return
	 */
	private Optimizer getOptimizerInstance(String className) {
		try {
			Class<?> clazz = Class.forName(className);
			return (Optimizer) clazz.getConstructor(new Class[] {}).newInstance(new Object[] {});
		} catch (ClassNotFoundException e) {
			this.logger.error(className,e);
			return null;
		} catch (SecurityException e) {
			this.logger.error(className,e);
			return null;
		} catch (NoSuchMethodException e) {
			this.logger.error(className,e);
			return null;
		} catch (IllegalArgumentException e) {
			this.logger.error(className,e);
			return null;
		} catch (InstantiationException e) {
			this.logger.error(className,e);
			return null;
		} catch (IllegalAccessException e) {
			this.logger.error(className,e);
			return null;
		} catch (InvocationTargetException e) {
			this.logger.error(className,e);
			return null;
		}
	}
}
